package fiuba.webapp.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.apache.struts2.ServletActionContext;

import fiuba.model.Configuracion;
import fiuba.service.GenericManager;
import fiuba.webapp.action.BaseAction;

public class HtmlEditorCommandsAction extends BaseAction {
	private String command;
	private String type;
	private String currentFolder;
	private String newFolderName;
	private Set<String> extensions; 
	
    private File NewFile;
    private String NewFileContentType;
    private String NewFileFileName;
	private GenericManager<Configuracion,Long> configuracionManager;

	public void setConfiguracionManager(
			GenericManager<Configuracion, Long> configuracionManager) {
		this.configuracionManager = configuracionManager;
	}
	

	// Creo que con un MAP o algo asi se habria hecho mas facil, pero no se hacerlo :/
	public class FileInfo {
		private String name;
		private Long size;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public Long getSize() {
			return size;
		}
		public void setSize(Long size) {
			this.size = size;
		}
		FileInfo(String name, Long size) {
			this.name = name;
			this.size = size;
		}
	}

	// Para armar el XML
    private List <String> folders = new ArrayList<String>();
    private List <FileInfo> filesInfo = new ArrayList<FileInfo>();
	private String browsePath = new String();
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -2713666065949212438L;
	
	public String obtenerXml() {
		//log.debug("COMANDO|TIPO|FOLDER: " + command + "|" + type + "|" + currentFolder);
		extensions = new HashSet<String>();
		// Dependiendo del tipo de archivo, mando las extensiones permitidas
		if (type.equals("Flash")) {
			extensions.add("swf");
		}
		if (type.equals("Image")) {
			extensions.add("jpg");
			extensions.add("jpeg");
			extensions.add("gif");
			extensions.add("png");
		}
		if (type.equals("File")) { // Para links, a documentos
			extensions.add("zip");
			extensions.add("rar");
			extensions.add("pdf");
			extensions.add("doc");
			extensions.add("xls");
		}
		
		// En base al comando, llamo al metodo que se encarga
		if (command.equalsIgnoreCase("GetFoldersAndFiles") || command.equals("GetFolders")) {
			armarListasArchivos(currentFolder);
		}
		if (command.equalsIgnoreCase("CreateFolder")){
			crearCarpeta(currentFolder,newFolderName);
		}
		if (command.equalsIgnoreCase("FileUpload")) {
			try { subirArchivo(currentFolder);
			} catch (Exception e) {
				log.debug("EXCEPCION EN EL UPLOAD");
			}
			return INPUT;
		}
		return SUCCESS;
	}

	public String getCommand() {
		return command;
	}

	public void setCommand(String command) {
		this.command = command;
	}

	public String getType() {
		return type;
	}

	public List<String> getFolders() {
		return folders;
	}

	public void setFolders(List<String> folders) {
		this.folders = folders;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getCurrentFolder() {
		return currentFolder;
	}

	public void setCurrentFolder(String currentFolder) {
		this.currentFolder = currentFolder;
	}
	
	private void armarListasArchivos(String path) {
		String mediaPath = this.configuracionManager.get(1L).getMediaPath();
		// medidas de seguridad: empieza con "/" y no tiene ".."
		if (path.charAt(0) != '/') path = "/";
		if (path.contains("..")) path = "/";
		// Directorio desde donde miro
        String lookupDir = ServletActionContext.getServletContext().getRealPath(mediaPath) + path;
        File dirPath = new File(lookupDir);
        if (!dirPath.exists()) { // Si no existe, vamos al raiz y ya
        	log.debug("Directorio que no existe: " + lookupDir);
        	path = "/";
        	lookupDir = ServletActionContext.getServletContext().getRealPath(mediaPath) + "/";
            dirPath = new File(lookupDir);
            if (!dirPath.exists()) {
            	log.debug("Directorio raiz que no existe: " + lookupDir);
            	return;
            }
        }
        // Devuelvo la listita
        File[] archs = dirPath.listFiles();
        for (int i=0; i < archs.length; i++) {
            // Get filename of file or directory
            File arch = archs[i];
            if (! arch.getName().startsWith(".")) { // Devolver solo si empieza sin punto
	            if (arch.isDirectory()) {
	            	this.folders.add(arch.getName());
	            }
	            else { // Si es archivo
	            	String extension = arch.getName().split("\\.")[arch.getName().split("\\.").length - 1];
	            	if (extensions.contains(extension.toLowerCase())) {
		            	this.filesInfo.add(new FileInfo(arch.getName(), (long) Math.ceil(arch.length()/1024) ));
	            	}
	            }
            }
        }
        browsePath = path;
	}

	private void crearCarpeta(String path, String nuevaCarpeta) {
		String mediaPath = this.configuracionManager.get(1L).getMediaPath();
		// medidas de seguridad: empieza con "/" y no tiene ".."
		if (path.charAt(0) != '/') path = "/";
		if (path.contains("..")) path = "/";
		// Directorio desde donde miro
        String lookupDir = ServletActionContext.getServletContext().getRealPath(mediaPath) + path;
        File dirPath = new File(lookupDir);
        if (!dirPath.exists()) { // Si no existe, no puedo hacer nada
        	log.debug("DIRECTORIO DONDE QUIERE CREAR CARPETA NO EXISTE: " + path);
        	return;
        }
        // Ahora armo el path con la nueva carpeta
        dirPath = new File(lookupDir + nuevaCarpeta);
        if (!dirPath.exists()) {
            dirPath.mkdirs();
        }		
	}
	
	public String getBrowsePath() {
		return browsePath;
	}

	public void setBrowsePath(String browsePath) {
		this.browsePath = browsePath;
	}

	public String getNewFolderName() {
		return newFolderName;
	}

	public void setNewFolderName(String newFolderName) {
		this.newFolderName = newFolderName;
	}

	public List<FileInfo> getFilesInfo() {
		return filesInfo;
	}

	public void setFilesInfo(List<FileInfo> filesInfo) {
		this.filesInfo = filesInfo;
	}
	
	public void subirArchivo(String path) throws Exception {
		String mediaPath = this.configuracionManager.get(1L).getMediaPath();
        String uploadDir = ServletActionContext.getServletContext().getRealPath(mediaPath) + path;
        File fileUploadDir = new File(uploadDir);
        if (!fileUploadDir.exists()) { // Si no existe, no puedo hacer nada
        	log.debug("DIRECTORIO DONDE QUIERE SUBIR ARCHIVO NO EXISTE: " + path);
        	return;
        }
        //Obtener los datos
        InputStream stream = new FileInputStream(NewFile);

        //Grabar en la salida
        OutputStream bos = new FileOutputStream(uploadDir + NewFileFileName);
        int bytesRead;
        byte[] buffer = new byte[8192];

        while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
            bos.write(buffer, 0, bytesRead);
        }
        bos.close();
        stream.close();
	}

	public File getNewFile() {
		return NewFile;
	}

	public void setNewFile(File newFile) {
		NewFile = newFile;
	}

	public String getNewFileContentType() {
		return NewFileContentType;
	}

	public void setNewFileContentType(String newFileContentType) {
		NewFileContentType = newFileContentType;
	}

	public String getNewFileFileName() {
		return NewFileFileName;
	}

	public void setNewFileFileName(String newFileFileName) {
		NewFileFileName = newFileFileName;
	}
	

}
